package com.yehun.utils;

import com.yehun.admin.controller.BaseController;
import com.yehun.model.MappingModel;
import org.apache.ibatis.io.ResolverUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class PackageUtils {

    public static Set<Class<? extends Class<?>>> getClasses(String packageString) {
        return getClasses(packageString, Object.class);
    }

    public static Set<Class<? extends Class<?>>> getClasses(Class type) {
        return getClasses(type.getPackage().getName(), type);
    }

    public static Set<Class<? extends Class<?>>> getClasses(String packageString, Class type) {
        ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
        resolverUtil.find(new ResolverUtil.IsA(type), packageString);
        return resolverUtil.getClasses();
    }

    public static List<MappingModel> getRequestMappings(Class type) {
        List<MappingModel> mappings = new LinkedList<>();
        MappingModel mappingModel;
        Set<Class<? extends Class<?>>> classes = getClasses(type);
        for (Class<?> classType : classes) {
            if (classType != type) {
                System.out.println(classType.getName());
                Annotation classAnnotation = AnnotationUtils.getClassAnnotation(RequestMapping.class, classType);
                String prefixUrl = "";
                if (classAnnotation != null) {
                    prefixUrl = String.format("/%s", ((RequestMapping)classAnnotation).value()[0]);
                }
                for (Method method : classType.getDeclaredMethods()) {
                    System.out.println(method.getName());
                    if (method.isAnnotationPresent(RequestMapping.class)) {
                        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                        String[] values = requestMapping.value();
                        for (String value : values) {
                            mappingModel = new MappingModel();
                            mappingModel.setPath(String.format("%s.%s", classType.getName(), method.getName()));
                            mappingModel.setName(requestMapping.name());
                            mappingModel.setUrl(String.format("%s/%s", prefixUrl, value));
                            System.out.println(String.format("%s/%s", prefixUrl, value));
                            mappings.add(mappingModel);
                        }
                    }

                }
            }
        }
        return mappings;
    }

    public static void main(String[] args) {
        List<MappingModel> mappings = new LinkedList<>();
        MappingModel mappingModel;
        Set<Class<? extends Class<?>>> classes = getClasses(BaseController.class);
        for (Class<?> classType : classes) {
            if (classType != BaseController.class) {
                System.out.println(classType.getName());
                Annotation classAnnotation = AnnotationUtils.getClassAnnotation(RequestMapping.class, classType);
                String prefixUrl = "";
                if (classAnnotation != null) {
                    prefixUrl = String.format("/%s", ((RequestMapping)classAnnotation).value()[0]);
                }
                for (Method method : classType.getDeclaredMethods()) {
                    System.out.println(method.getName());
                    if (method.isAnnotationPresent(RequestMapping.class)) {
                        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                        String[] values = requestMapping.value();
                        for (String value : values) {
                            mappingModel = new MappingModel();
                            mappingModel.setPath(String.format("%s.%s", classType.getName(), method.getName()));
                            mappingModel.setName(requestMapping.name());
                            mappingModel.setUrl(String.format("%s/%s", prefixUrl, value));
                            System.out.println(String.format("%s/%s", prefixUrl, value));
                            mappings.add(mappingModel);
                        }
                    }

                }
                //List<Annotation> annotations = AnnotationUtils.getMethodAnnotations(RequestMapping.class, classType);
                //for (Annotation methodAnnotation : annotations) {
                //    System.out.println(methodAnnotation.toString());
                //    RequestMapping requestMapping = (RequestMapping) methodAnnotation;
                //    String[] values = requestMapping.value();
                //    for (String value : values) {
                //        mappingModel = new MappingModel();
                //        mappingModel.setClassName(classType.getName());
                //        mappingModel.setName(requestMapping.name());
                //        mappingModel.setUrl(String.format("%s/%s", prefixUrl, value));
                //        System.out.println(String.format("%s/%s", prefixUrl, value));
                //        mappings.add(mappingModel);
                //    }
                //}
            }
        }
        System.out.println(JsonUtils.serialize(mappings));
    }
}
